﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Xml.Linq;
using EPiBoost.Core.Infrastructure.Interfaces.Repositories;

namespace EPiBoost.Core.Infrastructure.Repositories
{
    public class InMemoryRepository : IRepository
    {
			public static ConcurrentDictionary<Type, object> _collection = new ConcurrentDictionary<Type, object>();
        
        public List<TEntity> GetCollection<TEntity>() where TEntity : class
        {
            if (!_collection.ContainsKey(typeof(TEntity)))
            {
                _collection.TryAdd(typeof(TEntity), new List<TEntity>());
            }

            return _collection[typeof(TEntity)] as List<TEntity>;
        }
        
        public void SetCollection<TEntity>(List<TEntity> collection) where TEntity : class
        {
            if (!_collection.ContainsKey(typeof(TEntity)))
            {
							_collection.TryAdd(typeof(TEntity), collection);
            }
            else
            {
                _collection[typeof(TEntity)] = collection;
            }
        }

        public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
        {
            return GetCollection<TEntity>().AsQueryable() as IQueryable<TEntity>;
        }

        public IQueryable<TEntity> GetAll<TEntity>() where TEntity : class
        {
            return GetQuery<TEntity>();
        }

        public IQueryable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
        {
            return GetQuery<TEntity>().Where(predicate);
        }

        public TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
        {
            return GetQuery<TEntity>().Where(predicate).FirstOrDefault();
        }

        public TEntity Single<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
        {
            return GetQuery<TEntity>().Where(predicate).SingleOrDefault();
        }
          
        public void Add<TEntity>(TEntity entity) where TEntity : class
        {
            GetCollection<TEntity>().Add(entity);
        }

        public void Delete<TEntity>(TEntity entity) where TEntity : class
        {
            GetCollection<TEntity>().Remove(entity);
        }

        public void Attach<TEntity>(TEntity entity) where TEntity : class
        {
            //throw new NotImplementedException();
        }

        public void SaveChanges()
        {
            //throw new NotImplementedException();
        }

	    public void SaveChanges(SaveOptions options)
	    {
		    throw new NotImplementedException();
	    }


	    public void CancelChanges()
        {
            //throw new NotImplementedException();
        }

        public bool DisableCacheing { get; set; }
    }
}
